package com.asm.service;

import com.asm.dto.PageResult;
import com.asm.entity.sys.WorkOrder;
import com.asm.repository.WorkOrderRepository;
import com.asm.util.SnowflakeIdWorker;
import com.asm.vo.sys.*;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;


/**
 * @author zhangyufu
 * @description
 * @date 2019/7/12
 */
@Service
public class WorkOrderService {

    @Resource
    private WorkOrderRepository workOrderRepository;

    @Resource
    private SpotService spotService;

    @Resource
    private MaintenanceService maintenanceService;

    @Resource
    private BookService bookService;

    @Resource
    private CommunityService communityService;

    @Resource
    private SnowflakeIdWorker snowflakeIdWorker;

    /**
     * 获取工单位列表
     *
     * @param page 页面对象
     * @return 工单列表
     */
    private List<WorkOrderVo> getWorkOrderVoList(Page<WorkOrder> page) {
        List<WorkOrderVo> list = new ArrayList<>();
        for (WorkOrder workOrder : page.getContent()) {
            getVoList(list, workOrder);
        }
        return list;
    }

    /**
     * 将工单对象封装成工装显示对象并加入到list中
     *
     * @param list 数据列表
     * @param workOrder 工单信息
     */
    private void getVoList(List<WorkOrderVo> list, WorkOrder workOrder) {
        WorkOrderVo workOrderVo = new WorkOrderVo();
        BeanUtils.copyProperties(workOrder, workOrderVo);
        MaintenanceVo maintenanceVo = null;
        BookVo bookVo = null;
        switch (workOrder.getWorkType()) {
            case "安装单":  bookVo = bookService.findBookById(workOrder.getOrderId());
                            workOrderVo.setSellId(bookVo.getSellId());
                            break;
            case "维修单":  maintenanceVo = maintenanceService.findMaintenanceById(workOrder.getOrderId());
                            workOrderVo.setSellId(maintenanceService.findMaintenanceById(workOrderVo.getOrderId()).getSellId());
                            break;
            default:        break;
        }
        SpotVo spotVo = null;
        if (maintenanceVo != null) {
            spotVo = spotService.findSpotById(maintenanceVo.getSpotId());
            workOrderVo.setSpotId(spotVo.getId());
        }
        if (bookVo != null) {
            spotVo = spotService.findSpotById(bookVo.getSpotId());
            workOrderVo.setSpotId(spotVo.getId());
        }
        if (spotVo.getCommunityId() != null) {
            CommunityVo communityVo = communityService.getCommunity(spotVo.getCommunityId());
            workOrderVo.setAddress(communityVo.getAddress());
        }
        list.add(workOrderVo);
    }

    private List<WorkOrderVo> getWorkOrderVoList(List<WorkOrder> workOrderList){
        List<WorkOrderVo> list = new ArrayList<>();
        for (WorkOrder workOrder : workOrderList) {
            getVoList(list, workOrder);
        }
        return list;
    }

    /**
     * 根据id查询工单
     *
     * @param id 工单编号
     * @return 工单
     */
    public WorkOrderVo findWorkOrderById(Long id) {
        WorkOrder workOrder = workOrderRepository.findById(id).get();
        WorkOrderVo workOrderVo = new WorkOrderVo();
        BeanUtils.copyProperties(workOrder, workOrderVo);
        return workOrderVo;
    }

    /**
     * 根据工单状态查询相关工单信息
     *
     * @param status     工单状态
     * @param pageNumber 当前页码
     * @param pageSize   页面大小
     * @return 分页形式的工单列表
     */
    public PageResult<WorkOrderVo> findWorkOrderByStatus(String status, Integer pageNumber, Integer pageSize) {
        Pageable page = PageRequest.of(pageNumber, pageSize);
        Page<WorkOrder> workOrders = workOrderRepository.findByStatusAndIsDel(status, false, page);
        return new PageResult<>(pageNumber, pageSize, workOrders.getTotalPages(), getWorkOrderVoList(workOrders));
    }

    /**
     * 根据工人id查询相关工单信息
     *
     * @param workerId   工人id
     * @param pageNumber 当前页码
     * @param pageSize   页面大小
     * @return 分页形式的工单列表
     */
    public PageResult<WorkOrderVo> findWorkOrderByWorkerId(Long workerId, Integer pageNumber, Integer pageSize) {
        Pageable page = PageRequest.of(pageNumber, pageSize);
        Page<WorkOrder> workOrders = workOrderRepository.findByWorkerId(workerId, page);
        List<WorkOrderVo> workOrderVos = getWorkOrderVoList(workOrders);
        return new PageResult<>(pageNumber, pageSize, workOrders.getTotalPages(), workOrderVos);
    }

    /**
     * 根据业务员ID查找工单信息
     *
     * @param sellId 业务员ID
     * @return 工单列表
     */
    public List<WorkOrderVo> findWorkOrderBySellId(Long sellId){
        List<WorkOrder> maintenanceOrder = workOrderRepository.findWorkOrderByWorkType("维修单");
        List<WorkOrder> bookOrder = workOrderRepository.findWorkOrderByWorkType("安装单");
        List<WorkOrder> sellOrderList = new ArrayList<>();

        for (WorkOrder workOrder : maintenanceOrder) {
            MaintenanceVo maintenanceVo = maintenanceService.findMaintenanceById(workOrder.getOrderId());
            if (maintenanceVo.getSellId() == null) {
                continue;
            }
            if (maintenanceVo.getSellId().equals(sellId)){
                sellOrderList.add(workOrder);
            }
        }
        for (WorkOrder workOrder : bookOrder) {
            BookVo bookVo = bookService.findBookById(workOrder.getOrderId());
            if (bookVo.getSellId() == null) {
                continue;
            }
            if (bookVo.getSellId().equals(sellId)){
                sellOrderList.add(workOrder);
            }
        }

        return getWorkOrderVoList(sellOrderList);
    }

    /**
     * 添加工单
     *
     * @param workOrderVo 工单
     * @return 新生成的工单的id
     */
    @Transactional(rollbackFor = Exception.class)
    public Long addWorkOrder(WorkOrderVo workOrderVo) {
        WorkOrder workOrder = new WorkOrder();
        BeanUtils.copyProperties(workOrderVo, workOrder);
        workOrder.setId(snowflakeIdWorker.nextId());
        workOrder.setCreateAt(new Date());
        workOrder.setCreateBy(1L);
        workOrder.setUpdateAt(new Date());
        workOrder.setUpdateBy(1L);
        workOrderRepository.save(workOrder);
        return workOrder.getId();
    }

    /**
     * 更新工单
     *
     * @param workOrderVo 工单
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateWorkOrder(WorkOrderVo workOrderVo) {
        WorkOrder workOrder = workOrderRepository.findWorkOrderById(workOrderVo.getId());
        BeanUtils.copyProperties(workOrderVo, workOrder);
        workOrder.setUpdateBy(1L);
        workOrder.setUpdateAt(new Date());
        workOrderRepository.save(workOrder);
    }

    /**
     * 完成工单任务
     *
     * @param workOrderVo 工单
     */
    public void accomplishWorkOrder(WorkOrderVo workOrderVo) {
        workOrderVo.setStatus("完成");
        this.updateWorkOrder(workOrderVo);

        SpotVo spotVo = new SpotVo();

        String workType = "维修单";
        if (workType.equals(workOrderVo.getWorkType())) {
            MaintenanceVo maintenanceVo = maintenanceService.findMaintenanceById(workOrderVo.getOrderId());
            maintenanceVo.setStatus("维修完成");
            spotVo = spotService.findSpotById(maintenanceVo.getSpotId());
            spotVo.setIsRepair(false);
            spotVo.setIsBusy(false);
            maintenanceService.updateMaintenance(maintenanceVo);
        } else {
            BookVo bookVo = bookService.findBookById(workOrderVo.getOrderId());
            spotVo = spotService.findSpotById(bookVo.getSpotId());
            bookVo.setStatus("安装完成");
            spotVo.setIsRepair(false);
            bookService.updateBook(bookVo);
        }
        spotService.updateSpot(spotVo);
    }

    /**
     * 根据Id删除工单
     *
     * @param id 工单编号
     */
    @Transactional(rollbackFor = Exception.class)
    public void deleteWorkOrder(Long id) {
        WorkOrder workOrder = workOrderRepository.findById(id).get();
        workOrder.setIsDel(true);
        workOrder.setUpdateBy(1L);
        workOrder.setUpdateAt(new Date());
        workOrderRepository.save(workOrder);
    }

    /**
     * 分页查询所有工单
     *
     * @param pageNumber 当前页码
     * @param pageSize   页面大小
     * @return 分页形式的工单列表
     */
    public PageResult<WorkOrderVo> findAllWorkOrders(Integer pageNumber, Integer pageSize) {
        Page<WorkOrder> page = workOrderRepository.findAll(PageRequest.of(pageNumber, pageSize));
        return new PageResult<>(pageNumber, pageSize, page.getTotalPages(), getWorkOrderVoList(page));
    }

    /**
     * 分页查询所有工单，查询结果按工单状态排序
     *
     * @param pageNumber 当前页码
     * @param pageSize   页面大小
     * @return 分页并排序的工单
     */
    public PageResult<WorkOrderVo> getWorkOrderByStatusSort(Integer pageNumber, Integer pageSize) {
        Pageable page = PageRequest.of(pageNumber, pageSize);
        Page<WorkOrder> page1 = workOrderRepository.findByStatusAndIsDel("未完成", false, page);
        Page<WorkOrder> page2 = workOrderRepository.findByStatusAndIsDel("完成", false, page);
        List<WorkOrderVo> list1 = getWorkOrderVoList(page1);
        List<WorkOrderVo> list2 = getWorkOrderVoList(page2);
        List<List<WorkOrderVo>> workOrderLists = new ArrayList<>();
        workOrderLists.add(list1);
        workOrderLists.add(list2);
        List<WorkOrderVo> workOrderList = new ArrayList<>();
        for (int i = 0; i < workOrderLists.size(); i++) {
            List<WorkOrderVo> list = workOrderLists.get(i);
            for (int j = 0; j < list.size(); j++) {
                workOrderList.add(list.get(j));
            }
        }
        int totalPages = page1.getTotalPages() + page2.getTotalPages();
        return new PageResult<>(pageNumber, pageSize, totalPages, workOrderList);
    }

}
